package com.device;

import org.kabeja.dxf.*;
import org.kabeja.dxf.helpers.Point;
import org.kabeja.dxf.objects.DXFDictionary;
import org.kabeja.parser.ParseException;
import org.kabeja.parser.Parser;
import org.kabeja.parser.ParserBuilder;

import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.List;

/*
 * */
public class CadDataExtraction {

    private static final String[] colorCorrelation ={
            "0,0,0"
            ,"255,0,0"
            ,"255,255,0"
            ,"0,255,0"
            ,"0,255,255"
            ,"0,0,255"
            ,"255,0,255"
            ,"255,255,255"
            ,"128,128,128"
            ,"192,192,192"
            ,"255,0,0"
            ,"255,127,127"
            ,"204,0,0"
            ,"204,102,102"
            ,"153,0,0"
            ,"153,76,76"
            ,"127,0,0"
            ,"127,63,63"
            ,"76,0,0"
            ,"76,38,38"
            ,"255,63,0"
            ,"255,159,127"
            ,"204,51,0"
            ,"204,127,102"
            ,"153,38,0"
            ,"153,95,76"
            ,"127,31,0"
            ,"127,79,63"
            ,"76,19,0"
            ,"76,47,38"
            ,"255,127,0"
            ,"255,191,127"
            ,"204,102,0"
            ,"204,153,102"
            ,"153,76,0"
            ,"153,114,76"
            ,"127,63,0"
            ,"127,95,63"
            ,"76,38,0"
            ,"76,57,38"
            ,"255,191,0"
            ,"255,223,127"
            ,"204,153,0"
            ,"204,178,102"
            ,"153,114,0"
            ,"153,133,76"
            ,"127,95,0"
            ,"127,111,63"
            ,"76,57,0"
            ,"76,66,38"
            ,"255,255,0"
            ,"255,255,127"
            ,"204,204,0"
            ,"204,204,102"
            ,"153,153,0"
            ,"153,153,76"
            ,"127,127,0"
            ,"127,127,63"
            ,"76,76,0"
            ,"76,76,38"
            ,"191,255,0"
            ,"223,255,127"
            ,"153,204,0"
            ,"178,204,102"
            ,"114,153,0"
            ,"133,153,76"
            ,"95,127,0"
            ,"111,127,63"
            ,"57,76,0"
            ,"66,76,38"
            ,"127,255,0"
            ,"191,255,127"
            ,"102,204,0"
            ,"153,204,102"
            ,"76,153,0"
            ,"114,153,76"
            ,"63,127,0"
            ,"95,127,63"
            ,"38,76,0"
            ,"57,76,38"
            ,"63,255,0"
            ,"159,255,127"
            ,"51,204,0"
            ,"127,204,102"
            ,"38,153,0"
            ,"95,153,76"
            ,"31,127,0"
            ,"79,127,63"
            ,"19,76,0"
            ,"47,76,38"
            ,"0,255,0"
            ,"127,255,127"
            ,"0,204,0"
            ,"102,204,102"
            ,"0,153,0"
            ,"76,153,76"
            ,"0,127,0"
            ,"63,127,63"
            ,"0,76,0"
            ,"38,76,38"
            ,"0,255,63"
            ,"127,255,159"
            ,"0,204,51"
            ,"102,204,127"
            ,"0,153,38"
            ,"76,153,95"
            ,"0,127,31"
            ,"63,127,79"
            ,"0,76,19"
            ,"38,76,47"
            ,"0,255,127"
            ,"127,255,191"
            ,"0,204,102"
            ,"102,204,153"
            ,"0,153,76"
            ,"76,153,114"
            ,"0,127,63"
            ,"63,127,95"
            ,"0,76,38"
            ,"38,76,57"
            ,"0255,191"
            ,"127,255,223"
            ,"0,204,153"
            ,"102,204,178"
            ,"0,153,114"
            ,"76,153,133"
            ,"0,127,95"
            ,"63,127,111"
            ,"0,76,57"
            ,"38,76,66"
            ,"0,255,255"
            ,"127,255,255"
            ,"0,204,204"
            ,"102,204,204"
            ,"0,153,153"
            ,"76,153,153"
            ,"0,127,127"
            ,"63,127,127"
            ,"0,76,76"
            ,"38,76,76"
            ,"0,191,255"
            ,"127,223,255"
            ,"0,153,204"
            ,"102,178,204"
            ,"0,114,153"
            ,"76,13,153"
            ,"0,95,127"
            ,"63,111,127"
            ,"0,57,76"
            ,"38,66,76"
            ,"0,127,255"
            ,"127,191,255"
            ,"0,102,204"
            ,"102,153,204"
            ,"0,76,153"
            ,"76,114,153"
            ,"0,63,127"
            ,"63,95	127"
            ,"0,38,76"
            ,"38,57,76"
            ,"0,63,255"
            ,"127,159,255"
            ,"0,51,204"
            ,"102,127,204"
            ,"0,38,153"
            ,"76,95	153"
            ,"0,31,127"
            ,"63,79,127"
            ,"0,19,76"
            ,"38,47,76"
            ,"0,0,255"
            ,"127,127,255"
            ,"0,0,204"
            ,"102,102,204"
            ,"0,0,153"
            ,"76,76,153"
            ,"0,0,127"
            ,"63,63	127"
            ,"0,0,76"
            ,"38,38,76"
            ,"63,0,255"
            ,"159,127,255"
            ,"51,0,204"
            ,"127,102204"
            ,"38,0,153"
            ,"95,76,153"
            ,"31,0,127"
            ,"79,63,127"
            ,"19,0,76"
            ,"47,38,76"
            ,"127,0,255"
            ,"191,127,255"
            ,"102,0,204"
            ,"153,102,204"
            ,"76,0,153"
            ,"114,76,153"
            ,"63,0,127"
            ,"95,63,127"
            ,"38,0,76"
            ,"57,38,76"
            ,"191,0,255"
            ,"223,127,255"
            ,"153,0,204"
            ,"178,102,204"
            ,"114,0,153"
            ,"133,76,153"
            ,"95,0,127"
            ,"111,63,127"
            ,"57,0,76"
            ,"66,38,76"
            ,"255,0,255"
            ,"255,127,255"
            ,"204,0,204"
            ,"204,10,204"
            ,"153,0,153"
            ,"153,76,153"
            ,"127,0,127"
            ,"127,63,127"
            ,"76,0,76"
            ,"76,38,76"
            ,"255,0,191"
            ,"255,127,223"
            ,"204,0,153"
            ,"204,102,178"
            ,"153,0,114"
            ,"153,76,133"
            ,"127,0,95"
            ,"127,63,111"
            ,"76,0,57"
            ,"76,38,66"
            ,"255,0,127"
            ,"255,127,191"
            ,"204,0,102"
            ,"204,102,153"
            ,"153,0,76"
            ,"153,76,114"
            ,"127,0,63"
            ,"127,63,95"
            ,"76,0,38"
            ,"76,38,57"
            ,"255,0,63"
            ,"255,127,159"
            ,"204,0,51"
            ,"204,102,127"
            ,"153,0,38"
            ,"153,76,95"
            ,"127,0,31"
            ,"127,63,79"
            ,"76,0,19"
            ,"76,38,47"
            ,"51,51,51"
            ,"91,91,91"
            ,"132,132,132"
            ,"173,173,173"
            ,"214,214,214"
            ,"255,255,255"};
    /*
     1. 颜色选择器
     2. 确定未显示元素的数据
     */
    public static int[] getColorRGB(int color){
        String s = colorCorrelation[color];
        return  Arrays.stream(s.split(","))
                .mapToInt(Integer::parseInt)
                .toArray();
    }

    /*
    1. 提取后的数据要判断可见性
    2. 将可见的图层、图快、图元返回
     */
    //extract 图元类型
    public static ArrayList<String> getDXFEntityTypes(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<String> types = new ArrayList<>();
        HashSet<String> noRepeatTypes = new HashSet<>();
        for (DXFLayer dxfLayer:dxfLayers){
            Iterator iter = dxfLayer.getDXFEntityTypeIterator();
            while (iter.hasNext()){
                String type = (String) iter.next();
                noRepeatTypes.add(type);
            }
        }
        types.addAll(noRepeatTypes);
        return types;
    }
    /*
    根据图元类型提取数据
     */
    public static ArrayList<DXFLine> getDXFLines(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFLine> dxfLines = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_LINE);
            if(dxfEntities != null){
                dxfLines.addAll(dxfEntities);
            }
        }
        System.out.println("size"+dxfLines.size());
        return dxfLines;
    }
    public static ArrayList<DXFCircle> getDXFCircles(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFCircle> dxfCircles = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_CIRCLE);
            if(dxfEntities != null){
                dxfCircles.addAll(dxfEntities);
            }
        }
        return dxfCircles;
    }
    public static ArrayList<DXFArc> getDXFArcs(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFArc> dxfArcs = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_ARC);
            if(dxfEntities != null){
                dxfArcs.addAll(dxfEntities);
            }
        }
        return dxfArcs;
    }

    public static ArrayList<DXFPolyline> getDXFPolylines(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFPolyline> dxfPolylines = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_LWPOLYLINE);
            if(dxfEntities != null){
                dxfPolylines.addAll(dxfEntities);
            }
        }
        return dxfPolylines;
    }
    public static ArrayList<Point> getDXFPolylinePoints(DXFPolyline dxfPolyline){
        ArrayList<Point> dxfVertices = new ArrayList<>();
        Iterator iter = dxfPolyline.getVertexIterator();
        while(iter.hasNext()){
            DXFVertex next = (DXFVertex) iter.next();
            dxfVertices.add(next.getPoint());
        }
        return dxfVertices;
    }
    public static ArrayList<DXFInsert> getDXFInserts(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFInsert> dxfInserts = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_INSERT);
            if(dxfEntities != null){
                dxfInserts.addAll(dxfEntities);
            }
        }
        return dxfInserts;
    }public static ArrayList<DXFHatch> getDXFHatchs(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFHatch> dxfHatches = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_HATCH);
            if(dxfEntities != null){
                dxfHatches.addAll(dxfEntities);
            }
        }
        return dxfHatches;
    }
    public static ArrayList<DXFSpline> getDXFSplines(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFSpline> dxfSplines = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_SPLINE);
            if(dxfEntities != null){
                dxfSplines.addAll(dxfEntities);
            }
        }
        return dxfSplines;
    }
    public static ArrayList<DXFMText> getDXFMTexts(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFMText> dxfmTexts = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_MTEXT);
            if(dxfEntities != null){
                dxfmTexts.addAll(dxfEntities);
            }
        }
        return dxfmTexts;
    }
    public static ArrayList<DXFEllipse> getDXFEllipses(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFEllipse> dxfEllipses = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_ELLIPSE);
            if(dxfEntities != null){
                dxfEllipses.addAll(dxfEntities);
            }
        }
        return dxfEllipses;
    }
    public static ArrayList<DXFDimension> getDXFDimensions(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFDimension> dxfDimensions = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_DIMENSION);
            if(dxfEntities != null){
                dxfDimensions.addAll(dxfEntities);
            }
        }
        return dxfDimensions;
    }
    public static ArrayList<DXFViewport> getDXFViewports(DXFDocument doc){
        ArrayList<DXFLayer> dxfLayers = getDXFLayers(doc);
        ArrayList<DXFViewport> dxfViewports = new ArrayList<>();
        for (DXFLayer dxfLayer:dxfLayers){
            List dxfEntities = dxfLayer.getDXFEntities(DXFConstants.ENTITY_TYPE_VIEWPORT);
            if(dxfEntities != null){
                dxfViewports.addAll(dxfEntities);
            }
        }
        return dxfViewports;
    }

    //提取CAD每一个图块中的图元数据
    public static List<DXFEntity> getDXFEntitiesByDXFBlock(DXFBlock dxfBlock){
        ArrayList<DXFEntity> list = new ArrayList<>();
        Iterator iter = dxfBlock.getDXFEntitiesIterator();
        Integer num = 0;
        System.out.println("图块名称:"+dxfBlock.getName());
        while (iter.hasNext()){
            num++;
            DXFEntity next = (DXFEntity) iter.next();
            list.add(next);
        }
        return list;
    }
    //获取CAD图中尺寸标注信息
    public  static List<DXFDimensionStyle> getDXFDimensionStyle(DXFDocument dxfdoc){
        ArrayList<DXFDimensionStyle> list = new ArrayList<>();
        Iterator iter = dxfdoc.getDXFDimensionStyleIterator();
        while(iter.hasNext()){
            DXFDimensionStyle dxfDimensionStyle = (DXFDimensionStyle) iter.next();
            list.add(dxfDimensionStyle);
        }
        return list;

    }

    //提取CAD图中所有的图块
    public static ArrayList<DXFBlock> getDXFBlocks(DXFDocument dxfdoc){
        ArrayList<DXFBlock> dxfBlocks = new ArrayList<>();
        Iterator iter = dxfdoc.getDXFBlockIterator();
        while(iter.hasNext()){
            DXFBlock dXFBlock = (DXFBlock)iter.next();
            dxfBlocks.add(dXFBlock);
        }
        return dxfBlocks;
    }

    //获取所有的entity
    public static List<DXFEntity> getDXFEntities(DXFDocument dxfdoc){
        //创建一个用于存储实体对象的列表
        List<DXFEntity> list = new ArrayList<DXFEntity>();
        //获取DXF文档的图层迭代器
        Integer num = 0;
        Iterator iter = dxfdoc.getDXFLayerIterator();
        while(iter.hasNext()){//遍历每个图层
            //获取当前图层对象
            DXFLayer dXFLayer = (DXFLayer)iter.next();
            num++;
            //获取当前图层的实体类型列表
            List<String> l = getDXFEntityTypes(dXFLayer);
            for(String s : l){
                //获取当前实体类型下的所有实体对象列表
                List<DXFEntity> ld = dXFLayer.getDXFEntities(s);
                for(DXFEntity d : ld){
                    list.add(d);
                }
            }
        }
        return list;
    }

    //根据图层名称获取entity
    public static List<DXFEntity> getDXFEntitiesByLayerName(DXFDocument dxfdoc,String layerName){
        List<DXFEntity> list = new ArrayList<DXFEntity>();
        Iterator iter = dxfdoc.getDXFLayerIterator();
        while(iter.hasNext()){
            DXFLayer dXFLayer = (DXFLayer)iter.next();
            if(dXFLayer.getName().equals(layerName)){
                List<String> l = getDXFEntityTypes(dXFLayer);
                for(String s : l){
                    List<DXFEntity> ld = dXFLayer.getDXFEntities(s);
                    for(DXFEntity d : ld){
                        list.add(d);
                    }
                }
            }
        }
        return list;
    }
    //根据图层获取entity
    public static List<DXFEntity> getDXFEntitiesByLayer(DXFLayer dxfLayer){
        List<DXFEntity> list = new ArrayList<DXFEntity>();
        List<String> l = getDXFEntityTypes(dxfLayer);
        for(String s : l){
            List<DXFEntity> ld = dxfLayer.getDXFEntities(s);
            for(DXFEntity d : ld){
                if(d.isVisibile()) list.add(d);
            }
        }
        return list;
    }
    //提取CAD图中所有图层数据
    public static ArrayList<DXFLayer> getDXFLayers(DXFDocument dxfdoc){
        ArrayList<DXFLayer> dxfLayers = new ArrayList<>();
        Iterator iter = dxfdoc.getDXFLayerIterator();
        while(iter.hasNext()){
            DXFLayer dXFLayer = (DXFLayer)iter.next();
            if(dXFLayer.isVisible()) dxfLayers.add(dXFLayer);
//            getDXFSubEntityByEntity(dXFLayer);
        }
        System.out.println("Layers"+dxfLayers.size());
        return dxfLayers;
    }

    //通过DXFBlock获取entity
    public static List<DXFEntity> getEntityByDXFBlock(DXFBlock dXFBlock){
        List<DXFEntity> list = new ArrayList<DXFEntity>();
        Iterator iter = dXFBlock.getDXFEntitiesIterator();
        while(iter.hasNext()){
            DXFEntity d = (DXFEntity)iter.next();
            list.add(d);
        }
        return list;
    }

    //通过图层获取DXFEntityType
    public static List<String> getDXFEntityTypes(DXFLayer dXFLayer){
        List<String> list = new ArrayList<String>();
        Iterator iter = dXFLayer.getDXFEntityTypeIterator();
        while(iter.hasNext()){
            String d = (String)iter.next();
            list.add(d);
        }
        return list;
    }

    //getDXFLineTypeIterator()  线型
    public static List<DXFLineType> getDXFLineTypes(DXFDocument dxfdoc){
        List<DXFLineType> dXFLineTypes = new ArrayList<DXFLineType>();
        Iterator iter = dxfdoc.getDXFLineTypeIterator();
        while(iter.hasNext()){
            DXFLineType dXFLineType = (DXFLineType)iter.next();
            dXFLineTypes.add(dXFLineType);
        }
        return dXFLineTypes;
    }

    //getDXFStyleIterator()
    public static List<DXFStyle> getDXFStyles(DXFDocument dxfdoc){
        List<DXFStyle> dXFStyles = new ArrayList<DXFStyle>();
        Iterator iter = dxfdoc.getDXFStyleIterator();
        while(iter.hasNext()){
            DXFStyle dXFStyle = (DXFStyle)iter.next();
            dXFStyles.add(dXFStyle);
        }
        return dXFStyles;
    }

    //getDXFViewIterator()
    public static List<DXFView> getDXFViews(DXFDocument dxfdoc){
        List<DXFView> dXFViews = new ArrayList<DXFView>();
        Iterator iter = dxfdoc.getDXFViewIterator();
        while(iter.hasNext()){
            DXFView dXFView = (DXFView)iter.next();
            dXFViews.add(dXFView);
        }
        return dXFViews;
    }

}
